#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

sbit Buzzer = P2^5;

#define SPACE 500 //SPACE就是定义的4分音符为基准的，一般是四分音符，就是500ms

//音符与索引对应表，P：休止符，L：低音，M：中音，H：高音，下划线：升半音符号#
#define P	0
#define L1	1
#define L1_	2
#define L2	3
#define L2_	4
#define L3	5
#define L4	6
#define L4_	7
#define L5	8
#define L5_	9
#define L6	10
#define L6_	11
#define L7	12
#define M1	13
#define M1_	14
#define M2	15
#define M2_	16
#define M3	17
#define M4	18
#define M4_	19
#define M5	20
#define M5_	21
#define M6	22
#define M6_	23
#define M7	24
#define H1	25
#define H1_	26
#define H2	27
#define H2_	28
#define H3	29
#define H4	30
#define H4_	31
#define H5	32
#define H5_	33
#define H6	34
#define H6_	35
#define H7	36


//索引与频率对照表
unsigned int FreqTable[]={
	0,
	63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
	64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
	65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};

//unsigned char Music[]={//第一列表示小星星对应的频率序号表，第二列表示音符的几分音符
//						13,4,
//						13,4,
//						20,4,
//						20,4,
//						22,4,
//						22,4,
//						20,8,
//						18,4,
//						18,4,
//						17,4,
//						17,4,
//						15,4,
//						15,4,
//						13,8,
//	0xFF,
//};//小星星对应的频率序号表

//乐谱 天空之城
unsigned char code Music[]={ //因为RAM只有512个字节存不下去，所以用code存在flash里面
	//音符,时值,
	
	//1
	P,	4,
	P,	4,
	P,	4,
	M6,	2,
	M7,	2,
	
	H1,	4+2,
	M7,	2,
	H1,	4,
	H3,	4,
	
	M7,	4+4+4,
	M3,	2,
	M3,	2,
	
	//2
	M6,	4+2,
	M5,	2,
	M6, 4,
	H1,	4,
	
	M5,	4+4+4,
	M3,	4,
	
	M4,	4+2,
	M3,	2,
	M4,	4,
	H1,	4,
	
	//3
	M3,	4+4,
	P,	2,
	H1,	2,
	H1,	2,
	H1,	2,
	
	M7,	4+2,
	M4_,2,
	M4_,4,
	M7,	4,
	
	M7,	8,
	P,	4,
	M6,	2,
	M7,	2,
	
	//4
	H1,	4+2,
	M7,	2,
	H1,	4,
	H3,	4,
	
	M7,	4+4+4,
	M3,	2,
	M3,	2,
	
	M6,	4+2,
	M5,	2,
	M6, 4,
	H1,	4,
	
	//5
	M5,	4+4+4,
	M2,	2,
	M3,	2,
	
	M4,	4,
	H1,	2,
	M7,	2+2,
	H1,	2+4,
	
	H2,	2,
	H2,	2,
	H3,	2,
	H1,	2+4+4,
	
	//6
	H1,	2,
	M7,	2,
	M6,	2,
	M6,	2,
	M7,	4,
	M5_,4,
	
	
	M6,	4+4+4,
	H1,	2,
	H2,	2,
	
	H3,	4+2,
	H2,	2,
	H3,	4,
	H5,	4,
	
	//7
	H2,	4+4+4,
	M5,	2,
	M5,	2,
	
	H1,	4+2,
	M7,	2,
	H1,	4,
	H3,	4,
	
	H3,	4+4+4+4,
	
	//8
	M6,	2,
	M7,	2,
	H1,	4,
	M7,	4,
	H2,	2,
	H2,	2,
	
	H1,	4+2,
	M5,	2+4+4,
	
	H4,	4,
	H3,	4,
	H3,	4,
	H1,	4,
	
	//9
	H3,	4+4+4,
	H3,	4,
	
	H6,	4+4,
	H5,	4,
	H5,	4,
	
	H3,	2,
	H2,	2,
	H1,	4+4,
	P,	2,
	H1,	2,
	
	//10
	H2,	4,
	H1,	2,
	H2,	2,
	H2,	4,
	H5,	4,
	
	H3,	4+4+4,
	H3,	4,
	
	H6,	4+4,
	H5,	4+4,
	
	//11
	H3,	2,
	H2,	2,
	H1,	4+4,
	P,	2,
	H1,	2,
	
	H2,	4,
	H1,	2,
	H2,	2+4,
	M7,	4,
	
	M6,	4+4+4,
	P,	4,
	
	0xFF	//终止标志
};//天空之城


unsigned char FreqSelect,MusicSelect;

void main()
{
	Timer0_Init();
	while(1)
	{
		if(Music[MusicSelect]!= 0xFF)
		{
			FreqSelect = Music[MusicSelect];//这里取出来是音调
			MusicSelect++;
			Delay(SPACE/4*Music[MusicSelect]);//这里确定音调时长，因为你125ms就是以16音符为标准，一个16分音符就是125ms，乘以第二列就是几分音符，延长音符时间
			MusicSelect++;
			TR0= 0;
			Delay(5);
			TR0=1;
		}
		else
		{
			TR0= 0;
			while(1){}
		}
	}
}


void Timer0_Rountine() interrupt 1 //这个是中断号，就是相当于是你T0发生中断了，就会跳到这个地方来，interrupt 1就是T0的中断号，前面的名字是自己取的
{
	if(FreqTable[FreqSelect])
	{
		//这地方就是音调，上面主程序中断的时候进去换音调，他500ms进来一次，开关停的转化，但是不影响音调时间，这里只是闪跳，在音色延时的时候可能还是会进去，但是关闭斌率，然后在开，但是人耳听不出来，就认为一直在响
		TL0 = FreqTable[FreqSelect]%256;	
		TH0 = FreqTable[FreqSelect]/256;		//可以通过设计这个进入中断的时间（重装值），来实现不同频率，实现不同的音调
		Buzzer = !Buzzer;
	}
}